import json
import time
from django.utils.deprecation import MiddlewareMixin
from common.utils.logger import Logger

class RequestLogMiddleware(MiddlewareMixin):
    """
    请求日志中间件
    记录所有请求的详细信息
    """
    
    def process_request(self, request):
        # 记录请求开始时间
        request.start_time = time.time()
        
        # 获取请求信息
        request_data = {
            'path': request.path,
            'method': request.method,
            'ip': self.get_client_ip(request),
            'user_agent': request.META.get('HTTP_USER_AGENT', ''),
            'referer': request.META.get('HTTP_REFERER', ''),
            'params': self.get_request_params(request),
            'user': str(request.user) if hasattr(request, 'user') else 'anonymous',
            'device_info': self.get_device_info(request)
        }
        
        # 记录请求日志
        # 将请求日志写入日志文件，路径为settings.LOGGING配置的路径
        Logger.info(f"Request: {json.dumps(request_data, ensure_ascii=False)}", name='request')
        return None

    def process_response(self, request, response):
        # 计算请求处理时间
        if hasattr(request, 'start_time'):
            duration = time.time() - request.start_time
        else:
            duration = 0
            
        # 获取响应信息
        response_data = {
            'path': request.path,
            'method': request.method,
            'status_code': response.status_code,
            'duration': f"{duration:.3f}s",
            'content_type': response.get('Content-Type', ''),
            'content_length': response.get('Content-Length', ''),
        }
        
        # 如果是JSON响应，记录响应内容
        if 'application/json' in response.get('Content-Type', ''):
            try:
                response_content = json.loads(response.content.decode())
                # 避免记录过大的响应内容
                if isinstance(response_content, dict):
                    # 只记录响应码和消息
                    response_data['content'] = {
                        'code': response_content.get('code'),
                        'message': response_content.get('message')
                    }
            except:
                pass
                
        Logger.info(f"Response: {json.dumps(response_data, ensure_ascii=False)}", name='request')
        return response

    def get_client_ip(self, request):
        """获取客户端真实IP地址"""
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip

    def get_request_params(self, request):
        """获取请求参数"""
        params = {}
        
        # GET参数
        if request.GET:
            params['query'] = dict(request.GET)
            
        # POST参数
        if request.method == 'POST':
            if request.content_type and 'application/json' in request.content_type:
                try:
                    body = json.loads(request.body.decode())
                    params['body'] = body
                except:
                    params['body'] = '无法解析的JSON数据'
            else:
                params['form'] = dict(request.POST)
                
        # 文件
        if request.FILES:
            files = {}
            for key, file in request.FILES.items():
                files[key] = {
                    'name': file.name,
                    'size': file.size,
                    'content_type': file.content_type
                }
            params['files'] = files
            
        return params

    def get_device_info(self, request):
        """获取设备信息"""
        user_agent = request.META.get('HTTP_USER_AGENT', '')
        
        device_info = {
            'user_agent': user_agent,
            'platform': self.get_platform(user_agent),
            'browser': self.get_browser(user_agent),
            'is_mobile': self.is_mobile(user_agent),
            'language': request.META.get('HTTP_ACCEPT_LANGUAGE', ''),
            'encoding': request.META.get('HTTP_ACCEPT_ENCODING', '')
        }
        return device_info

    def get_platform(self, user_agent):
        """获取操作系统平台"""
        platforms = [
            ('Windows', 'Windows'),
            ('iPhone', 'iOS'),
            ('iPad', 'iOS'),
            ('Android', 'Android'),
            ('Linux', 'Linux'),
            ('Mac OS', 'MacOS'),
        ]
        
        for platform in platforms:
            if platform[0] in user_agent:
                return platform[1]
        return 'Unknown'

    def get_browser(self, user_agent):
        """获取浏览器类型"""
        browsers = [
            ('Chrome', 'Chrome'),
            ('Firefox', 'Firefox'),
            ('Safari', 'Safari'),
            ('Edge', 'Edge'),
            ('MSIE', 'IE'),
            ('Opera', 'Opera'),
        ]
        
        for browser in browsers:
            if browser[0] in user_agent:
                return browser[1]
        return 'Unknown'

    def is_mobile(self, user_agent):
        """判断是否为移动设备"""
        mobile_keywords = ['Mobile', 'Android', 'iPhone', 'iPad', 'Windows Phone']
        return any(keyword in user_agent for keyword in mobile_keywords) 